<?php
/**
 * https://gitee.com/Mao02
 * http://www.dazhetu.cn/
 * jay_fun 410136330@qq.com
 * Date: 2018/4/6 0006
 * Time: 上午 0:07
 */

namespace app\common\controller;

use think\Controller;
use think\Db;
use think\exception\PDOException;
use think\facade\Request;

/**
 * 后台基础控制器
 * Class BasicAdmin
 * @package app\common\controller
 */
class BasicAdmin extends Controller {
    /**
     * @var 控制器默认数据表
     */
    protected $table;

    /**
     * 表单快捷方法
     * @param null $db
     * @param string $tpl
     * @param string $pk
     * @param array $where
     * @return array|mixed|null|\PDOStatement|string|\think\Model
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
	protected function _form($db = null, $tpl = '', $pk='', $where = []) {
		$db = empty($db)?Db::name($this->table):$db;
		$pk = $pk?:($db->getPk()?:'id');
		$pkValue = Request::param($pk,$where[$pk]??null);
		if (Request::isGet()){
			$vo = ($pkValue !== null) ? $db->where($pk,$pkValue)->where($where)->find():[];
			if (false !== $this->_callback('_form_before', $vo, [])) {
				return $this->fetch($tpl,['vo'=>$vo]);
			}
			return $vo;
		}
		$data = Request::post();
		if (false !== $this->_callback('_form_before', $data, [])) {
			try{
				if (isset($data[$pk])){
					$result = $db->where($pk,$data[$pk])->where($where)->update($data);
					$last_id = $data[$pk];
				}else{
					$result = $db->insert($data);
                    $last_id = $db->getLastInsID();
                }
			}catch (PDOException $e){
				$this->error($e->getMessage());
			}
			//手动释放所有查询条件
            $db->removeOption();
            $last_data = $db->find($last_id);
			if (false !== $this->_callback('_form_after',  $last_data, $result)) {
				if ($result !== false) {
					$this->success('恭喜, 数据保存成功!', '');
				}
				$this->error('数据保存失败, 请稍候再试!');
			}else{
			    $this->error("表单后置操作失败，请检查数据！");
            }
		}
	}

    /**
     * 列表页快捷方法
     * @param null $db
     * @param bool $multipage
     * @param array $param
     * @return array|mixed|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
	protected function _list($db = null, $multipage=true, $param=[]) {
		$db = empty($db)?Db::name($this->table):$db;
		if (Request::isGet()){
			if ($multipage){
				$pageResult = $db->paginate(null,false,['query'=>$param]);
				$this->assign('page',$pageResult->render());
				$result = $pageResult->all();
			}else{
				$result = $db->select();
			}
			if (false !== $this->_callback('_list_before', $result, [])) {
				$this->assign('list',$result);
				return $this->fetch();
			}
			return $result;
		}
	}

    /**
     * 删除操作
     * @param $ids
     * @throws PDOException
     * @throws \think\Exception
     */
    protected function _del($ids)
    {
        $fields = Db::name($this->table)->getTableFields();
        if (in_array('is_deleted',$fields)){
            $res = Db::name($this->table)
                ->whereIn('id', $ids)
                ->update(['is_deleted' => 1]);
        }else{
            $res = Db::name($this->table)
                ->whereIn('id', $ids)
                ->delete();
        }
        if ($res) {
            $this->success('删除成功！', '');
        } else {
            $this->error("删除失败");
        }
    }

    /**
     * 数据字段切换
     * @param $id
     * @param $data
     * @throws PDOException
     * @throws \think\Exception
     */
    protected function _change($id,$data)
    {
        $res = Db::name($this->table)->where('id', $id)->update($data);
        if ($res) {
            $this->success('切换状态操作成功！');
        } else {
            $this->error('切换状态操作失败！');
        }
    }

	/**
	 * 回调唤起
	 * @param $method
	 * @param $data1
	 * @param $data2
	 * @return bool
	 */
	protected function _callback($method, &$data1, $data2)
	{
		foreach ([$method, "_" . $this->request->action() . "{$method}"] as $_method) {
			if (method_exists($this, $_method) && false === $this->$_method($data1, $data2)) {
				return false;
			}
		}
		return true;
	}
}